/*
	SnowstormXEntity.h

	Represents the entities within the game engine.
	Must be inherited from in order to define actions for custom behaviour.

	Author: Aidan Goddard  10/8/14
*/

#ifndef SNOWSTORMXENTITY_H_INCLUDED
#define SNOWSTORMXENTITY_H_INCLUDED

#include"SnowstormXExports.h"
#include"SnowstormXEngineVars.h"
#include<stdint.h>

#define REG_OFFSET_XMM6		0
#define REG_OFFSET_XMM7		2
#define REG_OFFSET_XMM8		4
#define REG_OFFSET_XMM9		6
#define REG_OFFSET_XMM10	8
#define REG_OFFSET_XMM11	10
#define REG_OFFSET_XMM12	12
#define REG_OFFSET_XMM13	14
#define REG_OFFSET_XMM14	16
#define REG_OFFSET_XMM15	18
#define REG_OFFSET_R12		20
#define REG_OFFSET_R13		21
#define REG_OFFSET_R14		22
#define REG_OFFSET_R15		23
#define REG_OFFSET_RDI		24
#define REG_OFFSET_RSI		25
#define REG_OFFSET_RBX		26
#define REG_OFFSET_RBP		27
#define REG_OFFSET_RSP		28
#define REG_OFFSET_RIP		29
#define REG_OFFSET_CALLRSP	30

#define DEFAULT_STACK_SIZE 16384

#define STACK_MAGIC 0xdeadbabebeefbeefULL

namespace Snowstorm
{
	__declspec(align(16))
	class Entity
	{
		//////////////////////////////////////////////////////////////////////////
		// entity stuff

		// exported functions
	public:
		virtual uint64_t Action(void *start_params);
		SNOWSTORMXDLL_API Entity();
		SNOWSTORMXDLL_API ~Entity();
		void SNOWSTORMXDLL_API SetName(wchar_t *name, wchar_t *sub_name, uint32_t id_1, uint32_t id_2);
		void SNOWSTORMXDLL_API MakeExecutionReady(void *start_params);

	protected:
		void SNOWSTORMXDLL_API Wait(double wait_time);

		
		// data
	public:
		bool executing;
		wchar_t *name;
		wchar_t *sub_name;
		uint32_t id_1;
		uint32_t id_2;


	protected:
		XVARS *ev;
		uint32_t SNOWSTORM_ENGINE_TID;

		///////////////////////////////////////////////////////////////////////////
		// execution control stuff

		// execution control functions (only usable within the engine)
	public:
		void Resume(uint32_t thread_ID);
		void GetStacks(uint64_t **entity_stack, uint64_t **thread_stack);
		void SetActionReturnCode(uint64_t return_code);
		uint64_t GetActionReturnCode();
		void InitExecutionData(void *start_params);
		void InitMapData();	// TODO: finish this
		void SetThreadID(uint32_t thread_id);

		// execution control variables
	private:
		uint64_t *stack;
		uint64_t action_return_code;
		uint64_t stack_size;
		double wait_time;
		void *start_params;
		uint64_t thread_stack;
		uint64_t entity_stack;

	};
};




#endif